package com.fulu.game.bi.advice;

import com.fulu.game.bi.common.exception.BizException;
import com.fulu.game.bi.entity.vo.ExceptionCode;
import com.fulu.game.bi.entity.vo.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.connector.ClientAbortException;
import org.apache.shiro.ShiroException;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartException;

import java.util.List;

@ControllerAdvice
@ResponseBody
@Slf4j
public class ExceptionHandlerAdvice {

    /**
     * 404错误
     */
    @ExceptionHandler(org.springframework.web.servlet.NoHandlerFoundException.class)
    public Result noHandlerFoundException(org.springframework.web.servlet.NoHandlerFoundException e) {
        log.error(e.getMessage(), e);
        return Result.error().msg("未找到对应页面");
    }

    /**
     * 必填参数为空
     */
    @ExceptionHandler(MissingServletRequestParameterException.class)
    public Result missingServletRequestParameterException(MissingServletRequestParameterException e) {
        log.error(e.getMessage(), e);
        return Result.error().msg("必填参数空:" + e.getParameterName());
    }

    /**
     * 用户认证异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(ShiroException.class)
    public Result handleUserAuthException(ShiroException e) {
        log.error("用户认证异常", e);
        return Result.nologin().msg(e.getMessage()).data(ExceptionCode.NOT_EXIST_USER_AUTH.toObject());
    }

    /**
     * 业务异常的父类
     *
     * @param e
     * @return
     */
    @SuppressWarnings("checkstyle:MethodName")
    @ExceptionHandler(BizException.class)
    public Result bizException(BizException e) {
        log.error("业务异常", e);
        return Result.error().msg(e.getMessage()).data(ExceptionCode.SERVER_ERROR.toObject());
    }

    /**
     * 统一异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(Exception.class)
    public Result handleException(Exception e) {
        log.error(e.getMessage(), e);
        return Result.error().msg("服务器错误!").data(ExceptionCode.SERVER_ERROR.toObject());
    }

    /**
     * 上传文件过大异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(MultipartException.class)
    public Result handleException(MultipartException e) {
        log.error("文件上传错误", e);
        return Result.error().msg("上传文件不能超过50M");
    }

    /**
     * 处理@Valid绑定注解的异常抛出
     *
     * @param e
     * @return
     */
    @ExceptionHandler(BindException.class)
    public Result bindException(BindException e) {
        List<ObjectError> errors = e.getAllErrors();
        StringBuilder sb = new StringBuilder();
        for (ObjectError error : errors) {
            sb.append(error.getDefaultMessage()).append(";");
        }
        if (sb.length() > 0) {
            sb.deleteCharAt(sb.length() - 1);
        }
        return Result.error().msg(sb.toString());
    }

    /**
     * org.apache.catalina.connector.ClientAbortException异常拦截
     *
     * @param ex ClientAbortException
     * @return
     */
    @ExceptionHandler(ClientAbortException.class)
    public Result handleClientAbortException(ClientAbortException ex) {
        log.error("发生clientAbortException");
        return null;
    }
}
